package apphttp

import (
	"net/http"
	"encoding/json"
	"fmt"
	"io"
	"os"

	"TanguyWeb/main/utils/dbutil"
	"TanguyWeb/main/utils"
	"TanguyWeb/main/bean"
	"TanguyWeb/main/session"
	"TanguyWeb/main/config"
	"gitee.com/DengAnbang/goutils/loge"
)

func Run(port string) {
	var err error = nil
	config.LocalIP, err = config.GetIP()
	loge.W(config.LocalIP)
	CheckErr(err)
	//db, err := dbutil.Init(dbutil.DbConfig{SqlName: "root", SqlPwd: "root123456", SqlAddress: "localhost", SqlPort: "3306", SqlDatabaseName: "TanguyWeb"})
	db, err := dbutil.Init(dbutil.DbConfig{SqlName: "root", SqlPwd: "root123456", SqlAddress: "118.24.71.63", SqlPort: "13306", SqlDatabaseName: "TanguyWeb"})
	//db, err := dbutil.Init(dbutil.DbConfig{SqlName: "root", SqlPwd: "root123456", SqlAddress: config.LocalIP, SqlPort: "3306", SqlDatabaseName: "TanguyWeb"})
	CheckErr(err)
	addHandle()
	addHandleFunc()
	loge.W("开始启动服务..")
	err = http.ListenAndServe(":"+port, nil)
	CheckErr(err)
	loge.W("关闭服务")
	defer db.Close()
}

type FileHandler struct {}

func (f FileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fileName := fileutils.RootPath + r.URL.String()
	loge.E(fileName)
	if fileutils.PathExists(fileName) {
		f, _ := os.Stat(fileName)
		if !f.IsDir() {
			http.ServeFile(w, r, fileName)
			return
		}
	}
	http.NotFound(w, r)

}
func addHandle() {
	http.Handle("/app/file/", http.StripPrefix("/app/file/", FileHandler{}))
	http.Handle("/showLog/", http.StripPrefix("/showLog/", http.FileServer(http.Dir(fileutils.RootPath+"log"))))
}
func addHandleFunc() {
	handleFunc := make(map[string]func(http.ResponseWriter, *http.Request) (error))
	handleFunc["/"] = notFoundHandler
	handleFunc["/test"] = test
	//handleFunc["/showLog"] = showLog
	handleFunc["/app/smsRecord/sendSms"] = sendSms
	handleFunc["/app/user/register"] = register
	handleFunc["/app/user/login"] = login
	handleFunc["/app/file/upload"] = upload
	handleFunc["/app/html/test"] = htmlTest
	//handleFunc["/app/file"] = viewHandler
	for k, v := range handleFunc {
		http.HandleFunc(k, appHandleFunc(v))
	}
}

type appHandleFuncErr func(http.ResponseWriter, *http.Request) (error)

/**
统一处理错误
 */
func appHandleFunc(appHandleFuncErr appHandleFuncErr) (func(http.ResponseWriter, *http.Request)) {
	return func(writer http.ResponseWriter, request *http.Request) {
		defer func() {
			i := recover()
			if resultData, ok := i.(*bean.ResultData); ok {
				writerResult(writer, resultData)
			} else if err, ok := i.(error); ok {
				data := bean.ResultData{Code: -1, Msg: "服务器内部错误", DebugMeg: err.Error()}
				writerResult(writer, &data)
			}
		}()
		err := appHandleFuncErr(writer, request)
		if resultData, ok := err.(*bean.ResultData); ok {
			writerResult(writer, resultData)
			return
		}
		if err != nil {
			writerResult(writer, &bean.ResultData{Code: -1, Msg: "服务器内部错误", DebugMeg: err.Error()})
		}

	}
}

/**
公共方法
 */
func writerResult(w io.Writer, resultData *bean.ResultData) {
	bytes, err := json.Marshal(resultData)
	CheckErr(err)
	fmt.Fprint(w, string(bytes))
}
func CheckErr(err error) {
	if err != nil {
		loge.Fatalf("%T err:%s", err, err)
	}
}

/**
检测Session
如果过期,返回错误
如果不存在,返回nil
 */
func checkSession(request *http.Request) (*session.Session, error) {
	values := request.Form
	sessionID := values.Get("sessionID")
	if len(sessionID) > 0 {
		if newSession, ok := session.GetSession(sessionID); !ok {
			return nil, bean.NewResultError(config.OutOfDate, "登陆过期!")
		} else {
			return newSession.UpLastTimeAccessed(), nil
		}
	}
	return nil, nil
}
